package com.credit.web.basic;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.credit.context.CreditServletContext;
import com.credit.entity.CreditPaymentOrder;
import com.credit.entity.CreditUserInfo;
import com.credit.exception.ErrorException;
import com.credit.service.CreditCoinService;
import com.credit.service.CreditPaymentOrderService;
import com.credit.util.Constants;
import com.credit.util.OrderUtil;
import com.credit.util.ParamsConstant;
import com.credit.web.basic.bean.ResBean;

@Controller
@RequestMapping("/payment")
public class PaymentController {
	private static final Log log = LogFactory.getLog(PaymentController.class);
	@Autowired
	private CreditPaymentOrderService creditPaymentOrderService;
	@Autowired
	private CreditCoinService creditCoinService;
	
	
	@ResponseBody
	@RequestMapping(value = "/alipayOrder", method = RequestMethod.POST)
	public void alipayOrder(HttpServletRequest request, HttpServletResponse response )
			throws ErrorException, IllegalArgumentException, IllegalAccessException {
        
		String coins = request.getParameter("coins");
		
		Integer amount = ParamsConstant.COIN_LIST_MAP.get(Integer.valueOf(coins));
		if(amount == null || amount == 0){
			amount = Integer.valueOf(coins);
		}
		
		CreditPaymentOrder paymentOrder = getOrder(amount,coins);
		
		//实例化客户端
		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", ParamsConstant.ALIPAY_APP_ID, ParamsConstant.APP_PRIVATE_KEY, "json", "utf-8", ParamsConstant.ALIPAY_PUBLIC_KEY, "RSA");
		//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
		//SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setBody(coins+"金币");
		model.setSubject("金币");
		model.setOutTradeNo(paymentOrder.getOrderId());
		model.setTimeoutExpress("30m");
		model.setTotalAmount(String.valueOf(amount));
		model.setProductCode("QUICK_MSECURITY_PAY");
		alipayRequest.setBizModel(model);
		alipayRequest.setNotifyUrl(ParamsConstant.ALIPAY_NOTIFY_URL);
		try {
		        //这里和普通的接口调用不同，使用的是sdkExecute
		        AlipayTradeAppPayResponse resultResponse = alipayClient.sdkExecute(alipayRequest);
		        log.info(resultResponse.getBody());//就是orderString 可以直接给客户端请求，无需再做处理。
		        
		        ResBean resBean = CreditServletContext.getResBean();
		        resBean.getData().put("alipayOrder", resultResponse.getBody());
		        CreditServletContext.setResBean(resBean);
		        
		    } catch (AlipayApiException e) {
		        e.printStackTrace();
		}
		
		
	}

	private CreditPaymentOrder getOrder(Integer amount,String coins) {
		CreditUserInfo userInfo = CreditServletContext.getUserInfo();
		CreditPaymentOrder paymentOrder = new CreditPaymentOrder();
		paymentOrder.setOrderId(OrderUtil.getOrderId());
		paymentOrder.setCreateTime(new Date());
		paymentOrder.setPayChannelId("1");
		paymentOrder.setPayType("1");
		paymentOrder.setPayUserId(userInfo.getId());
		paymentOrder.setStatus("0");
		paymentOrder.setTradeName(coins);
		paymentOrder.setUpdateTime(new Date());
		paymentOrder.setAmount(new BigDecimal(amount));
		
		creditPaymentOrderService.addPaymentOrder(paymentOrder);
		
		return paymentOrder;
	}

	
	@ResponseBody
	@RequestMapping(value = "/notify", method = RequestMethod.POST)
	public void notify(HttpServletRequest request, HttpServletResponse response )
			throws ErrorException, IllegalArgumentException, IllegalAccessException, IOException {
        
		//获取支付宝POST过来反馈信息
		Map<String,String> params = new HashMap<String,String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
		    String name = (String) iter.next();
		    String[] values = (String[]) requestParams.get(name);
		    String valueStr = "";
		    for (int i = 0; i <values.length; i++) {
		        valueStr = (i == values.length - 1) ? valueStr + values[i]
		                    : valueStr + values[i] + ",";
		  }
		  //乱码解决，这段代码在出现乱码时使用。
		  //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
		  params.put(name, valueStr);
		 }
		//切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
		//boolean AlipaySignature.rsaCheckV1(Map
		
		try {
			boolean flag = AlipaySignature.rsaCheckV1(params, ParamsConstant.ALIPAY_PUBLIC_KEY, "utf-8", "RSA");
			if(flag){
				
				//为用户添加金币
				//添加金币日志
				String out_trade_no = request.getParameter("out_trade_no");
				CreditPaymentOrder paymentOrder = creditPaymentOrderService.findPaymentOrderById(out_trade_no);
				
				if(!paymentOrder.getStatus().equals("0")){
					throw new ErrorException(Constants.PAYMENT_FINISH_ERROR_CODE, Constants.PAYMENT_FINISH_ERROR_DESC);
				}
				
				String coins = paymentOrder.getTradeName();
				
				creditCoinService.increase(paymentOrder,Integer.valueOf(coins));
				
			}
		} catch (AlipayApiException e) {
			
			e.printStackTrace();
		}finally{
			response.getWriter().write("success");
			response.getWriter().flush();
			response.getWriter().close();
		}
		
		
	}
	
}
